using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
using System.Reflection;

namespace DacTaHinhThuc
{
    public abstract class Generator
    {
        #region fields        
        protected string m_sFileExtension;          //ten mo rong cua file
        protected string m_sFileName = "\\MyFile";  //ten file source code output
                
        protected Parser m_parser;        
        protected CodeDomProvider m_myProvider;   //luu provider de phat sinh ra code C# hay VB
        protected string[] m_arrNamespaceImport = { "System", "System.Collections.Generic", "System.Text" };

        protected Parameter m_arr;
        protected Parameter m_len;
        protected string m_sNot;            //luu lai toan tu Not cho moi ngon ngu:
                                            //m_sNot = "!" -> CS
                                            //m_sNot = "Not" ->VB
        #endregion
              
        #region properties
        public CodeDomProvider Provider
        {
            get { return this.m_myProvider; }
            set { this.m_myProvider = value; }
        }
        public string FileName
        {
            get { return this.m_sFileName; }
            set { this.m_sFileName = value; }
        }
        public string FileExtension
        {
            get { return this.m_sFileExtension; }
            set { this.m_sFileExtension = value; }
        }
        #endregion

        #region methods
        #region generate structures: properties, fields, methods...
        /// <summary>
        /// ham generate ra cac properties cua class
        /// </summary>
        /// <param name="sName">ten properties</param>
        /// <param name="type">loai properties (public, private, protected)</param>
        /// <param name="sNameField">ten cua field trong properties</param>
        /// <param name="hasGet">property co Get hay ko?</param>
        /// <param name="hasSet">property co Set hay ko?</param>
        /// <returns>tra ve CodeMemberProperty</returns>
        public CodeMemberProperty GenerateProperties(string sName,string sType,string sNameField, bool hasGet, bool hasSet)
        {
            CodeMemberProperty property1 = new CodeMemberProperty();
            property1.Name = sName;            
            property1.Type = new CodeTypeReference(sType);
            property1.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            
            if (hasGet)
            {
                property1.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), sNameField)));
            }
            if (hasSet)
            {
                property1.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), sNameField), new CodePropertySetValueReferenceExpression()));
            }
            return property1;
        }

        public CodeMemberProperty GenerateProperties(Parameter p,bool hasSet,bool hasGet)
        {
            CodeMemberProperty property1 = new CodeMemberProperty();
            property1.Name = "Property_" + p.Name.ToUpper();
            string str = "";
            if (p.IsArr)
            {
                str = "[]";
            }
            property1.Type = new CodeTypeReference(p.SystemType+str);
            property1.Attributes = MemberAttributes.Public | MemberAttributes.Final;

            if (hasGet)
            {
                property1.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), p.Name)));
            }
            if (hasSet)
            {
                property1.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), p.Name), new CodePropertySetValueReferenceExpression()));
            }
            return property1;
        }

        /// <summary>
        /// ham phat sinh ra namespace
        /// </summary>
        /// <param name="sName">ten cua namespace</param>
        /// <returns>tra ve CodeNamespace</returns>
        public CodeNamespace GenerateNamespace(string sName)
        {
            CodeNamespace codenamespace = new CodeNamespace(sName);
            codenamespace.Comments.Add(new CodeCommentStatement(""));
            codenamespace.Comments.Add(new CodeCommentStatement("Add code here"));
            codenamespace.Comments.Add(new CodeCommentStatement(""));
            return codenamespace;
        }

        /// <summary>
        /// ham de generate ra cac thu vien import vao source code
        /// </summary>
        /// <param name="arr">mang ten cac thu vien</param>
        /// <returns>tra ve cac CodeNamespaceImport</returns>
        public CodeNamespaceImport[] GenerateImport(string[] arr)
        {
            CodeNamespaceImport[] cni = new CodeNamespaceImport[arr.Length];
            int i;
            for (i = 0; i < arr.Length; i++)
            {
                cni[i] = new CodeNamespaceImport(arr[i]);
            }
            return cni;
        }

        /// <summary>
        /// ham de generate ra cac fields cua class
        /// </summary>
        /// <param name="sType">loai du lieu (int,float...)</param>
        /// <param name="sName">ten cua field</param>
        /// <param name="atribute">thuoc tinh (public,private..)</param>
        /// <returns>tra ve CodeMemberField</returns>
        public CodeMemberField GenerateField(string sType, string sName, string atribute)
        {
            CodeMemberField cmf = new CodeMemberField(sType, sName);
            cmf.Attributes = GetMemberAttribute(atribute);            
            return cmf;
        }

        public CodeMemberField GenerateField(Parameter p)
        {
            string str = "";
            if (p.IsArr)
            {
                str = "[]";
            }
           
            CodeMemberField cmf = new CodeMemberField(p.SystemType+str, p.Name);
            cmf.Attributes = MemberAttributes.Private;                     
            
            return cmf;
        }


        /// <summary>
        /// ham de generate constructor
        /// </summary>
        /// <param name="arrPara">danh sach tham so</param>
        /// <param name="col">danh sach cau lenh</param>
        /// <returns>tra ve constructor</returns>
        public CodeConstructor GenerateConstructor(Parameter[] arrPara,CodeStatementCollection col)
        {
            CodeConstructor cc = new CodeConstructor();
            cc.Attributes = MemberAttributes.Public;

            //add tham so
            foreach (Parameter p in arrPara)
            {
                cc.Parameters.Add(new CodeParameterDeclarationExpression(p.Type, p.Name));
            }

            //add cau lenh
            foreach (CodeStatement cs in col)
            {
                cc.Statements.Add(cs);
            }
            
            return cc;
        }

        /// <summary>
        /// ham phat sinh ra default constructor
        /// </summary>
        /// <returns>tra ve constructor</returns>
        public CodeConstructor GenerateConstructor()
        {
            CodeConstructor cc = new CodeConstructor();
            cc.Attributes = MemberAttributes.Public;
            
            //add comment
            cc.Comments.Add(this.GenerateComment(""));
            cc.Comments.Add(this.GenerateComment("default constructor"));
            cc.Comments.Add(this.GenerateComment(""));                               

            return cc;
        }
                       
        #region Generate Methods
        /// <summary>
        /// ham de phat sinh ra cac phuong thuc
        /// </summary>
        /// <param name="sName">ten phuong thuc</param>
        /// <param name="arrPara">danh sach tham so</param>
        /// <param name="result">ket qua tra ve</param>
        /// <param name="att">thuoc tinh(public,private...)</param>
        /// <param name="col">tap cac cau lenh trong ham</param>
        /// <returns></returns>
        public CodeMemberMethod GenerateMethod(string sName, Parameter[] arrPara, Parameter result, string att, CodeStatementCollection col)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = sName;
            method.Attributes = GetMemberAttribute(att);

            //tao danh sach tham so
            if (arrPara != null)
            {
                int i;
                for (i = 0; i < arrPara.Length; i++)
                {
                    CodeParameterDeclarationExpression cpde = new CodeParameterDeclarationExpression(arrPara[i].Type, arrPara[i].Name);
                    method.Parameters.Add(cpde);
                }
            }

            //ket qua tra ve
            method.ReturnType = new CodeTypeReference(result.Type);

            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }
            return method;
        }

        /// <summary>
        /// phat sinh ham khong co gia tri tra ve (void)
        /// </summary>
        /// <param name="sName">ten ham</param>
        /// <param name="arrPara">danh sach tham so</param>
        /// <param name="att">thuoc tinh ham</param>
        /// <param name="col">tap hop cau lenh trong ham</param>
        /// <returns>tra ve ham khong co gia tri tra ve</returns>
        public CodeMemberMethod GenerateMethod(string sName, Parameter[] arrPara, string att, CodeStatementCollection col)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = sName;
            method.Attributes = GetMemberAttribute(att);

            //tao danh sach tham so
            if (arrPara != null)
            {
                int i;
                for (i = 0; i < arrPara.Length; i++)
                {
                    CodeParameterDeclarationExpression cpde = new CodeParameterDeclarationExpression(arrPara[i].Type, arrPara[i].Name);
                    method.Parameters.Add(cpde);
                }
            }

            //ket qua tra ve
            method.ReturnType = null;

            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }
            return method;
        }
<<<<<<< .mine

        /// <summary>
        /// ham de phat sinh ham nhap
        /// </summary>
        /// <param name="sName">ten cua ham</param>
        /// <param name="arrPara">danh sach tham so truyen vao</param>
        /// <param name="att">ten thuoc tinh</param>
        /// <param name="sTypeReturn">kieu tra ve</param>
        /// <param name="col">danh sach cac cau lenh trong ham nhap</param>
        /// <returns>tra ve ham nhap</returns>
        public CodeMemberMethod GenerateInputMethod(string sName, Parameter[] arrPara, string att, string sTypeReturn,CodeStatementCollection col)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Input_" + sName;
            method.Attributes = GetMemberAttribute(att);

            //add comment
            method.Comments.Add(this.GenerateComment(""));
            method.Comments.Add(this.GenerateComment("Input method"));
            method.Comments.Add(this.GenerateComment(""));

            if (this.m_parser.Num == 1)
            {
                //viet cau lenh nhap cho danh sach tham so
                if (arrPara != null)
                {
                    int i;
                    for (i = 0; i < arrPara.Length; i++)
                    {
                        //tao doi tuong tham chieu den class system.console
                        CodeTypeReferenceExpression csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");

                        //tao cau xuat thong bao nhap
                        CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(csSystemConsoleType, "WriteLine");
                        cs1.Parameters.Add(this.GenerateExpression("\"Nhap vao gia tri cua bien " + arrPara[i].Name + ": \""));

                        method.Statements.Add(cs1);

                        CodeAssignStatement assign;
                        //tao cau lenh system.readline roi parse
                        if (arrPara[i].Type != "string")
                        {
                            //tao cau lenh Parse(System.ReadLine())
                            CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");
                            CodeTypeReferenceExpression csParse = new CodeTypeReferenceExpression(arrPara[i].SystemType);
                            CodeMethodInvokeExpression cs3 = new CodeMethodInvokeExpression(csParse, "Parse");
                            cs3.Parameters.Add(cs4);

                            //gan bien = 
                            assign = new CodeAssignStatement(new CodeVariableReferenceExpression(this.m_parser.ArrPara[i].Name), cs3);
                        }
                        else
                        {
                            //tao cau lenh (System.ReadLine())
                            CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");

                            //gan bien = 
                            assign = new CodeAssignStatement(new CodeVariableReferenceExpression(this.m_parser.ArrPara[i].Name), cs4);
                        }

                        method.Statements.Add(assign);
                    }
                }
            }
            else
            {
                //lam bai 2 o day
                //qui uoc: so nguyen dau tien dung ke mang la chieu dai cua mang
                int k = 0;
                                
                for (k = 0; k < this.m_parser.ArrPara.Length; k++)
                {
                    if (this.m_parser.ArrPara[k].IsArr)
                    {
                        this.m_arr = this.m_parser.ArrPara[k];
                    }
                    else
                    {
                        this.m_len = this.m_parser.ArrPara[k];
                    }
                }                                
                //tao cau nhap vao n la chieu dai mang
                //tao doi tuong tham chieu den class system.console
                CodeTypeReferenceExpression csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");

                //tao cau xuat thong bao nhap
                CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(csSystemConsoleType, "WriteLine");
                cs1.Parameters.Add(this.GenerateExpression("\"Nhap vao gia tri cua bien " + this.m_len.Name + ": \""));

                method.Statements.Add(cs1);

                CodeAssignStatement assign;
                //tao cau lenh system.readline roi parse
                if (this.m_len.Type != "string")
                {
                    //tao cau lenh Parse(System.ReadLine())
                    CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");
                    CodeTypeReferenceExpression csParse = new CodeTypeReferenceExpression(this.m_len.SystemType);
                    CodeMethodInvokeExpression cs3 = new CodeMethodInvokeExpression(csParse, "Parse");
                    cs3.Parameters.Add(cs4);

                    //gan bien = 
                    assign = new CodeAssignStatement(new CodeVariableReferenceExpression(this.m_len.Name), cs3);
                }
                else
                {
                    //tao cau lenh (System.ReadLine())
                    CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");

                    //gan bien = 
                    assign = new CodeAssignStatement(new CodeVariableReferenceExpression(this.m_len.Name), cs4);
                }

                method.Statements.Add(assign);
                               
                //xuat ra cau new doi tuong
                //T_T
                CodeArrayCreateExpression codeCr = new CodeArrayCreateExpression( new CodeTypeReference(this.m_arr.SystemType), new CodeVariableReferenceExpression(this.m_len.Name));
                CodeAssignStatement codeAss = new CodeAssignStatement(new CodeVariableReferenceExpression(this.m_arr.Name), codeCr);
                method.Statements.Add(codeAss);
                                
                //tao vong lap for(int i=0;i<len;i++)
                //tao cau int i = 0;
                CodeVariableDeclarationStatement initStment = new CodeVariableDeclarationStatement(typeof(int), "i");
                initStment.InitExpression = new CodeVariableReferenceExpression("0");               
                
                //tao dieu kien i<len
                CodeBinaryOperatorExpression cboe = new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("i"), CodeBinaryOperatorType.LessThan, new CodeVariableReferenceExpression(this.m_len.Name));
                //tao cau i++;
                CodeAssignStatement cas = new CodeAssignStatement(new CodeVariableReferenceExpression("i"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("i"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)));
                CodeIterationStatement forStment = this.GenerateForStatement(initStment, cboe, cas,null);
                       
                
                //tao cac cau thong bao nhap
                //tao doi tuong tham chieu den class system.console
                //CodeTypeReferenceExpression csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");
                csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");

                //tao cau xuat thong bao nhap
                //CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(csSystemConsoleType, "WriteLine");
                cs1 = new CodeMethodInvokeExpression(csSystemConsoleType, "WriteLine");
                
                
                cs1.Parameters.Add(this.GenerateExpression("\"Nhap vao gia tri cua phan tu thu i: \""));

                forStment.Statements.Add(cs1);                
                
                //cai nay dung
                //CodeAssignStatement assign;
                
                
                //tao cau lenh system.readline roi parse
                if (this.m_arr.Type != "string")
                {
                    //tao cau lenh Parse(System.ReadLine())
                    CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");
                    CodeTypeReferenceExpression csParse = new CodeTypeReferenceExpression(this.m_arr.SystemType);
                    CodeMethodInvokeExpression cs3 = new CodeMethodInvokeExpression(csParse, "Parse");
                    cs3.Parameters.Add(cs4);

                    //index
                    CodeIndexerExpression indexerExpression = new CodeIndexerExpression(this.GenerateExpression(this.m_arr.Name), new CodeVariableReferenceExpression("i"));

                    //gan bien = 
                    assign = new CodeAssignStatement(indexerExpression, cs3);
                }
                else
                {
                    //tao cau lenh (System.ReadLine())
                    CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");

                    //index
                    CodeIndexerExpression indexerExpression = new CodeIndexerExpression(this.GenerateExpression(this.m_arr.Name), new CodeVariableReferenceExpression("i"));

                    //gan bien = 
                    assign = new CodeAssignStatement(indexerExpression, cs4);
                    
                }

                forStment.Statements.Add(assign);
                
                method.Statements.Add(forStment);
            }

            //ket qua tra ve
            if (sTypeReturn == null)
            {
                //ket qua tra ve
                method.ReturnType = null;
            }
            else
            {
                method.ReturnType = this.GetCodeTypeReference(sTypeReturn);
            }

            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }

            return method;
        }

        public CodeMemberMethod GenerateOutputMethod(string sName, string att, string sTypeReturn, CodeStatementCollection col)
        {

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Output_" + sName;
            method.Attributes = GetMemberAttribute(att);

            //add comment
            method.Comments.Add(this.GenerateComment(""));
            method.Comments.Add(this.GenerateComment("Output method"));
            method.Comments.Add(this.GenerateComment(""));


            //tao doi tuong tham chieu den class system.console
            CodeTypeReferenceExpression csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");

            //tao cau xuat 
            CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(csSystemConsoleType, "WriteLine");
            cs1.Parameters.Add(this.GenerateExpression("\"Gia tri cua ket qua la: {0}\"," + this.m_parser.Result.Name));

            method.Statements.Add(cs1);


            if (sTypeReturn == null)
            {
                //ket qua tra ve
                method.ReturnType = null;
            }
            else
            {
                method.ReturnType = this.GetCodeTypeReference(sTypeReturn);
            }

            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }
            return method;
        }

        /// <summary>
        /// ham xu ly chinh
        /// </summary>
        /// <param name="sName">ten ham</param>
        /// <param name="att">thuoc tinh</param>
        /// <param name="col">danh sach cau lenh</param>
        /// <returns>tra ve ham chinh</returns>
        public CodeMemberMethod GenerateExecuteMethod(string sName, string att, CodeStatementCollection col)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Execute_" + sName;
            method.Attributes = GetMemberAttribute(att);

            //add comment
            method.Comments.Add(this.GenerateComment(""));
            method.Comments.Add(this.GenerateComment("Execute method"));
            method.Comments.Add(this.GenerateComment(""));

            method.ReturnType = null;

            if (this.m_parser.Num == 1)
            {
                CodeConditionStatement[] arrIf = new CodeConditionStatement[this.m_parser.PostCondition.Length];                               

                int k = 0;
                int j = 0;
                int i = 0;

                for (i = 0; i < arrIf.Length; i++)
                {
                    string[] arrCondition = this.m_parser.PostCondition[i].Split(new string[] { mySymbol.And }, StringSplitOptions.None);

                    string[] tmp = new string[arrCondition.Length - 1];

                    for (j = arrCondition.Length - 1; j > 0; j--)
                    {
                        arrCondition[j] = arrCondition[j].Trim();
                       
                        tmp[j - 1] = arrCondition[j];

                        //chuan hoa so sanh
                        for (k = 0; k < tmp[j - 1].Length; k++)
                        {
                            if (tmp[j - 1][k] == '=' && tmp[j - 1][k - 1] != '>' && tmp[j - 1][k - 1] != '<' && tmp[j - 1][k - 1] != '!')
                            {
                                tmp[j - 1] = tmp[j - 1].Insert(k, "=");
                                k++;
                            }
                        }
                    }

                    arrIf[i] = this.GeneraterIf(tmp, arrCondition[0].Trim());
                    method.Statements.Add(arrIf[i]);
                }
            }
            else
            {
                //lam bai 2 o day                               
                CodeIterationStatement forStament = null;
                int index=0;
                CodeAssignStatement initKq;
                forStament = this.GenerateForStatement(this.m_parser.PostCondition, ref index,out initKq);

                this.GenerateForStatement(this.m_parser.PostCondition[0], out initKq);
                method.Statements.Add(initKq);
                method.Statements.Add(forStament);               
            }
                
            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }
            return method;
        }
                
        public CodeMemberMethod GenerateCheckingMethod(string sName, string att, CodeStatementCollection col)
        {            

            //co nen chia ra bai 1 va 2 hay ko???????

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "KiemTra_" + sName;
            method.Attributes = GetMemberAttribute(att);

            //add comment
            method.Comments.Add(this.GenerateComment(""));
            method.Comments.Add(this.GenerateComment("Checking method"));
            method.Comments.Add(this.GenerateComment(""));

            method.ReturnType = this.GetCodeTypeReference("bool");

            //if (this.m_parser.Num == 1)
            {
                //kiem tra va return
                //return true
                CodeMethodReturnStatement returnTrue = new CodeMethodReturnStatement(this.GenerateExpression("true"));

                //return false
                CodeMethodReturnStatement returnFalse = new CodeMethodReturnStatement(this.GenerateExpression("false"));

                if (this.m_parser.PreCondition.Length > 0)
                {
                    string[] arr = this.m_parser.PreCondition;

                    CodeConditionStatement[] arrIf = new CodeConditionStatement[arr.Length];
                    int i;
                    string[] tmp;
                    for (i = 0; i < arrIf.Length - 1; i++)
                    {
                        tmp = arr[i].Split(new string[] { mySymbol.And }, StringSplitOptions.None);
                        arrIf[i] = new CodeConditionStatement();
                        arrIf[i].Condition = this.GenerateCompareStatement("&&",tmp);
                        arrIf[i].TrueStatements.Add(returnTrue);
                        //arrIf[i].FalseStatements.Add(returnFalse);

                        method.Statements.Add(arrIf[i]);
                    }

                    tmp = arr[i].Split(new string[] { mySymbol.And }, StringSplitOptions.None);
                    arrIf[i] = new CodeConditionStatement();
                    arrIf[i].Condition = this.GenerateCompareStatement("&&",tmp);
                    arrIf[i].TrueStatements.Add(returnTrue);
                    arrIf[i].FalseStatements.Add(returnFalse);

                    method.Statements.Add(arrIf[i]);
                }
                else
                {
                    CodeConditionStatement co = new CodeConditionStatement();

                    co.Condition = this.GenerateExpression("true");

                    co.TrueStatements.Add(returnTrue);
                    co.FalseStatements.Add(returnFalse);

                    method.Statements.Add(co);
                }
            }
            //else
            //{
            //    //lam bai 2 o day

            //}

            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }
            return method;
        } 

=======

        /// <summary>
        /// ham de phat sinh ham nhap
        /// </summary>
        /// <param name="sName">ten cua ham</param>
        /// <param name="arrPara">danh sach tham so truyen vao</param>
        /// <param name="att">ten thuoc tinh</param>
        /// <param name="sTypeReturn">kieu tra ve</param>
        /// <param name="col">danh sach cac cau lenh trong ham nhap</param>
        /// <returns>tra ve ham nhap</returns>
        public CodeMemberMethod GenerateInputMethod(string sName, Parameter[] arrPara, string att, string sTypeReturn,CodeStatementCollection col)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Input_" + sName;
            method.Attributes = GetMemberAttribute(att);

            //add comment
            method.Comments.Add(this.GenerateComment(""));
            method.Comments.Add(this.GenerateComment("Input method"));
            method.Comments.Add(this.GenerateComment(""));

            if (this.m_parser.Num == 1)
            {

                //viet cau lenh nhap cho danh sach tham so
                if (arrPara != null)
                {
                    int i;
                    for (i = 0; i < arrPara.Length; i++)
                    {
                        //tao doi tuong tham chieu den class system.console
                        CodeTypeReferenceExpression csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");

                        //tao cau xuat thong bao nhap
                        CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(csSystemConsoleType, "WriteLine");
                        cs1.Parameters.Add(this.GenerateExpression("\"Nhap vao gia tri cua bien " + arrPara[i].Name + ": \""));

                        method.Statements.Add(cs1);

                        CodeAssignStatement assign;
                        //tao cau lenh system.readline roi parse
                        if (arrPara[i].Type != "string")
                        {
                            //tao cau lenh Parse(System.ReadLine())
                            CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");
                            CodeTypeReferenceExpression csParse = new CodeTypeReferenceExpression(arrPara[i].SystemType);
                            CodeMethodInvokeExpression cs3 = new CodeMethodInvokeExpression(csParse, "Parse");
                            cs3.Parameters.Add(cs4);

                            //gan bien = 
                            assign = new CodeAssignStatement(new CodeVariableReferenceExpression(this.m_parser.ArrPara[0].Name), cs3);
                        }
                        else
                        {
                            //tao cau lenh (System.ReadLine())
                            CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");

                            //gan bien = 
                            assign = new CodeAssignStatement(new CodeVariableReferenceExpression(this.m_parser.ArrPara[0].Name), cs4);
                        }

                        method.Statements.Add(assign);
                    }
                }
            }
            else
            {
                //lam bai 2 o day
            }

            //ket qua tra ve
            if (sTypeReturn == null)
            {
                //ket qua tra ve
                method.ReturnType = null;
            }
            else
            {
                method.ReturnType = this.GetCodeTypeReference(sTypeReturn);
            }

            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }

            return method;
        }

        public CodeMemberMethod GenerateOutputMethod(string sName, string att, string sTypeReturn, CodeStatementCollection col)
        {

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Output_" + sName;
            method.Attributes = GetMemberAttribute(att);

            //add comment
            method.Comments.Add(this.GenerateComment(""));
            method.Comments.Add(this.GenerateComment("Output method"));
            method.Comments.Add(this.GenerateComment(""));

            if (this.m_parser.Num == 1)
            {
                //tao doi tuong tham chieu den class system.console
                CodeTypeReferenceExpression csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");

                //tao cau xuat 
                CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(csSystemConsoleType, "WriteLine");
                cs1.Parameters.Add(this.GenerateExpression("\"Gia tri cua ket qua la: {0}\"," + this.m_parser.Result.Name));

                method.Statements.Add(cs1);

                
            }
            else
            {
                //lam bai 2 o day
            }
            
            if (sTypeReturn == null)
            {
                //ket qua tra ve
                method.ReturnType = null;
            }
            else
            {
                method.ReturnType = this.GetCodeTypeReference(sTypeReturn);
            }

            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }
            return method;
        }

        /// <summary>
        /// ham xu ly chinh
        /// </summary>
        /// <param name="sName">ten ham</param>
        /// <param name="att">thuoc tinh</param>
        /// <param name="col">danh sach cau lenh</param>
        /// <returns>tra ve ham chinh</returns>
        public CodeMemberMethod GenerateExecuteMethod(string sName, string att, CodeStatementCollection col)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Execute_"+ sName;
            method.Attributes = GetMemberAttribute(att);

            //add comment
            method.Comments.Add(this.GenerateComment(""));
            method.Comments.Add(this.GenerateComment("Execute method"));
            method.Comments.Add(this.GenerateComment(""));

            method.ReturnType = null;

            if (this.m_parser.Num == 1)
            {
                CodeConditionStatement[] arrIf = new CodeConditionStatement[this.m_parser.PostCondition.Length];

                string[] arr = { mySymbol.And };

                int k = 0;
                int j = 0;
                int i = 0;
                for (i = 0; i < arrIf.Length; i++)
                {                   
                   
                    string[] arrCondition = this.m_parser.PostCondition[i].Split(arr, StringSplitOptions.None);

                    string[] tmp = new string[arrCondition.Length - 1];
                    for (j = arrCondition.Length - 1; j > 0; j--)
                    {
                        arrCondition[j] = arrCondition[j].Trim();

                        arrCondition[j] = arrCondition[j].Replace("(", "");
                        arrCondition[j] = arrCondition[j].Replace(")", "");

                        tmp[j - 1] = arrCondition[j];

                        //chuan hoa so sanh
                        for (k = 0; k < tmp[j - 1].Length; k++)
                        {
                            if (tmp[j - 1][k] == '=' && tmp[j - 1][k - 1] != '>' && tmp[j - 1][k - 1] != '<')
                            {
                                tmp[j - 1] = tmp[j - 1].Insert(k, "=");
                                k++;
                            }
                        }
                    }

                    arrIf[i] = this.GeneraterIf(tmp, arrCondition[0].Trim());
                    method.Statements.Add(arrIf[i]);
                }
            }
            else
            {
                //lam bai 2 o day
            }

            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }
            return method;
        }
      
        /// <summary>
        /// ham de phat sinh ra code kiem tra
        /// </summary>
        /// <param name="sName"></param>
        /// <param name="att"></param>
        /// <param name="col"></param>
        /// <returns></returns>
        public CodeMemberMethod GenerateCheckingMethod(string sName, string att, CodeStatementCollection col)
        {
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "KiemTra_" + sName;
            method.Attributes = GetMemberAttribute(att);
                        
            //add comment
            method.Comments.Add(this.GenerateComment(""));
            method.Comments.Add(this.GenerateComment("Checking method"));
            method.Comments.Add(this.GenerateComment(""));

            method.ReturnType = this.GetCodeTypeReference("int");

            if (this.m_parser.Num == 1)
            {
                //kiem tra va return
                //return true
                CodeMethodReturnStatement returnTrue = new CodeMethodReturnStatement(new CodePrimitiveExpression(1));

                //return false
                CodeMethodReturnStatement returnFalse = new CodeMethodReturnStatement(new CodePrimitiveExpression(0));
                if (this.m_parser.PreCondition != "")
                {
                    string[] arr = this.m_parser.PreCondition.Split(new string[] { mySymbol.Or }, StringSplitOptions.None);

                    CodeConditionStatement[] arrIf = new CodeConditionStatement[arr.Length];
                    int i;
                    for (i = 0; i < arrIf.Length; i++)
                    {
                        string[] tmp = arr[i].Split(new string[] { mySymbol.And }, StringSplitOptions.None);
                        arrIf[i] = new CodeConditionStatement();
                        arrIf[i].Condition = this.GenerateCompareStatement(tmp);
                        arrIf[i].TrueStatements.Add(returnTrue);
                        arrIf[i].FalseStatements.Add(returnFalse);

                        method.Statements.Add(arrIf[i]);
                    }
                }
                else
                {
                    CodeConditionStatement co = new CodeConditionStatement();

                    co.Condition = this.GenerateCompareStatement(1, "==", 1);
                    co.TrueStatements.Add(returnTrue);
                    co.FalseStatements.Add(returnFalse);

                    method.Statements.Add(co);
                }
            }
            else
            {
                //lam bai 2 o day
            }
            
            //add code
            if (col != null)
            {
                foreach (CodeStatement cs in col)
                {
                    method.Statements.Add(cs);
                }
            }
            return method;
        } 

>>>>>>> .r17
        #endregion

        #endregion

        #region get enums
        /// <summary>
        /// ham de xac dinh loai toan tu de generate code
        /// </summary>
        /// <param name="s">toan tu can xac dinh</param>
        /// <returns>tra ve CodeBinaryOperatorType tuong ung</returns>
        private CodeBinaryOperatorType GetOperatorType(string s)
        {
            switch (s)
            {
                case ">":
                    return CodeBinaryOperatorType.GreaterThan;                    
                case"<":
                    return CodeBinaryOperatorType.LessThan;
                case">=":
                    return CodeBinaryOperatorType.GreaterThanOrEqual;
                case"<=":
                    return CodeBinaryOperatorType.LessThanOrEqual;
                case"==":
<<<<<<< .mine
                    return CodeBinaryOperatorType.ValueEquality;
                case"!=":
=======
                    return CodeBinaryOperatorType.ValueEquality;
                case"<>":
>>>>>>> .r17
                    return CodeBinaryOperatorType.IdentityInequality;
                case"&&":
                    return CodeBinaryOperatorType.BooleanAnd;
                case"||":
                    return CodeBinaryOperatorType.BooleanOr;
                case"&":
                    return CodeBinaryOperatorType.BitwiseAnd;
                case"|":
                    return CodeBinaryOperatorType.BitwiseOr;
                case"+":
                    return CodeBinaryOperatorType.Add;
                case"-":
                    return CodeBinaryOperatorType.Subtract;
                case"*":
                    return CodeBinaryOperatorType.Multiply;
                case"/":
                    return CodeBinaryOperatorType.Divide;
                case"=":
                    return CodeBinaryOperatorType.Assign;
                case"mod":
                case"%":
                    return CodeBinaryOperatorType.Modulus;                    
                default:
                    return CodeBinaryOperatorType.ValueEquality;
            }           
        }

        /// <summary>
        /// ham de xac dinh loai cua thuoc tinh cua member(public, private...)
        /// </summary>
        /// <param name="s">ten</param>
        /// <returns>tra ve MemberAttribute</returns>
        private MemberAttributes GetMemberAttribute(string s)
        {
            s = s.ToLower();
            switch (s)
            {
                case "public":
<<<<<<< .mine
                    return MemberAttributes.Public | MemberAttributes.Final;
=======
                    return MemberAttributes.Public | MemberAttributes.Final;

                //case "protected":        //ko co protected ????????????
                //    //cmf.Attributes =  MemberAttributes.prot
                //    return 
>>>>>>> .r17
                case "private":
<<<<<<< .mine
                    return MemberAttributes.Private | MemberAttributes.Final;
                case "abstract":
=======
                    return MemberAttributes.Private | MemberAttributes.Final;
                case"abstract":
>>>>>>> .r17
                    return MemberAttributes.Abstract;
                case "static":
                    return MemberAttributes.Static;
                case "override":
                    return MemberAttributes.Override;
                default:
                    return MemberAttributes.VTableMask; //chang bit la cai gi :D
            }
        }

        /// <summary>
        /// xac dinh thuoc tinh cua class
        /// </summary>
        /// <param name="s">ten</param>
        /// <returns>tra ve thuoc tinh cua class</returns>
        private TypeAttributes GetTypeAttribute(string s)
        {
            s = s.ToLower();
            switch (s)
            {
                case"public":
                    return TypeAttributes.Public;
                case"abstract":
                    return TypeAttributes.Abstract;
                case"interface":
                    return TypeAttributes.Interface;                
                default:
                    return TypeAttributes.Sealed;                    
            }
        }

        private CodeTypeReference GetCodeTypeReference(string s)
        {
            s = s.ToLower();
            switch (s)
            {
                case"int":
                    return new CodeTypeReference("System.Int32");
                case"float":
                    return new CodeTypeReference("System.Single");
                case"long":
                    return new CodeTypeReference("System.Int64");
                case"bool":
                    return new CodeTypeReference("System.Boolean");
                case"string":
                    return new CodeTypeReference("System.String");
                case"void":
                    return null;
                default:
                    return null;
            }
        }
        #endregion               
        
        #region generate statements: if, for ...
        #region If Statement
<<<<<<< .mine
        
=======
        /*
>>>>>>> .r17
        /// <summary>
        /// ham de phat sinh if
        /// </summary>
        /// <param name="condition">dieu kien if</param>
        /// <param name="colTrueStment">danh sach cac cau lenh khi if dung</param>
        /// <returns>tra ve cau lenh if</returns>
        public CodeConditionStatement GeneraterIf(string[] condition,params string[] colTrueStment)
        {
            CodeConditionStatement conditionStatement = new CodeConditionStatement();
            if (condition.Length > 0)
            {
                string str = "";
                foreach (string s in condition)
                {
                    //str += "(" + s + ")" + "&&";
                    str += s + "&&";
                }
                str = str.Substring(0, str.Length - 2);

                conditionStatement.Condition = this.GenerateCompareStatement("&&",condition);
            }
            else
            {
                conditionStatement.Condition = this.GenerateCompareStatement(1, "==", 1);
            }

            for (int i = 0; i < colTrueStment.Length; i++)
            {
                colTrueStment[i] = colTrueStment[i].Replace("(", "");
                colTrueStment[i] = colTrueStment[i].Replace(")", "");

                conditionStatement.TrueStatements.Add(this.GenerateExpression(colTrueStment[i]));
            }           

            return conditionStatement;
        }
        */
<<<<<<< .mine
        public CodeConditionStatement[] GeneraterIf(string condition, params CodeStatement[] colTrueStment)
=======
        /// <summary>
        /// ham de phat sinh if
        /// </summary>
        /// <param name="condition">dieu kien if</param>
        /// <param name="colTrueStment">danh sach cac cau lenh khi if dung</param>
        /// <returns>tra ve cau lenh if</returns>
        public CodeConditionStatement GeneraterIf(string[] condition,params string[] colTrueStment)
>>>>>>> .r17
        {
            CodeConditionStatement[] arrIf;
            string[] arr1;
            string[] arr2;
            string sNot = "";
            if (condition[0] == '!')
            {
                condition = condition.Substring(1, condition.Length - 1);
            if (condition.Length > 0)
            {
                string str = "";
                foreach (string s in condition)
                {
                    str += "(" + s + ")" + "&&";
                }
                str = str.Substring(0, str.Length - 2);

<<<<<<< .mine
                //xu ly cho truong hop !a
                if (!condition.Contains(">") && !condition.Contains("<") && !condition.Contains("="))
                {
                    arrIf = new CodeConditionStatement[1];
                    arrIf[0] = new CodeConditionStatement();
                    
                    arrIf[0].Condition = this.GenerateExpression(this.m_sNot + condition);
                    if (colTrueStment != null)
                    {
                        foreach (CodeStatement s in colTrueStment)
                        {
                            arrIf[0].TrueStatements.Add(s);
                        }
                    }
                    return arrIf;
                }
                else
                {                    
                    condition = condition.Replace("/\\", "||");
                    condition = condition.Replace("\\/", "&&");

                    arr1 = new string[] { "&&" };
                    arr2 = new string[] { "||" };

                    sNot = "!";

                    string[] arr = condition.Split(arr1, StringSplitOptions.RemoveEmptyEntries);
                    int i;

                    string[] arrOr;
                    int j;

                    CodeBinaryOperatorExpression[] arrIfAnd = new CodeBinaryOperatorExpression[arr.Length];
                    for (j = 0; j < arr.Length; j++)
                    {
                        arrOr = arr[j].Split(arr2, StringSplitOptions.RemoveEmptyEntries);
                        for (i = 0; i < arrOr.Length; i++)
                        {
                            arrOr[i] = this.ConvertNotExpression("!" + arrOr[i]);
                        }
                        //noi lai cac or
                        arrIfAnd[j] = this.GenerateCompareStatement("||", arrOr);
                    }

                    //noi lai cac and
                    arrIf = new CodeConditionStatement[1];
                    arrIf[0] = new CodeConditionStatement();
                    arrIf[0].Condition = this.GenerateCompareStatement("&&", arrIfAnd);
                    if (colTrueStment != null)
                    {
                        foreach (CodeStatement s in colTrueStment)
                        {
                            arrIf[0].TrueStatements.Add(s);
                        }
                    }
                    return arrIf;
                }
            }
            else
=======
                conditionStatement.Condition = this.GenerateCompareStatement(condition);
            }
            else
            {
                conditionStatement.Condition = this.GenerateCompareStatement(1, "==", 1);
            }

            for (int i = 0; i < colTrueStment.Length; i++)
            {
                colTrueStment[i] = colTrueStment[i].Replace("(", "");
                colTrueStment[i] = colTrueStment[i].Replace(")", "");

                conditionStatement.TrueStatements.Add(this.GenerateExpression(colTrueStment[i]));
            }

            return conditionStatement;
        }

        /// <summary>
        /// ham de phat sinh if
        /// </summary>
        /// <param name="condition">dieu kien if</param>
        /// <param name="colTrueStment">danh sach cau lenh khi if dung</param>
        /// <param name="colFalseStment">danh sach cau lenh khi if sai</param>
        /// <returns>tra ve cau lenh if</returns>
        public CodeStatement GeneraterIf(string condition, string[] colTrueStment, string[] colFalseStment)
        {
            CodeConditionStatement conditionStatement = new CodeConditionStatement();

            conditionStatement.Condition = this.GenerateExpression(condition);
            foreach (string cs in colTrueStment)
>>>>>>> .r17
            {
                arr1 = new string[] { "\\/" };
                arr2 = new string[] { "/\\" };

                sNot = "";

                string[] arr = condition.Split(arr1, StringSplitOptions.RemoveEmptyEntries);
                int i;
                for (i = 0; i < arr.Length; i++)
                {
                    arr[i] = this.ConvertNotExpression(sNot + arr[i]);
                }

                arrIf = new CodeConditionStatement[arr.Length];
                string[] tmp;
                for (i = 0; i < arrIf.Length; i++)
                {
                    tmp = arr[i].Split(arr2, StringSplitOptions.RemoveEmptyEntries);
                    arrIf[i] = new CodeConditionStatement();
                    arrIf[i].Condition = this.GenerateCompareStatement("&&",tmp);
                    foreach (CodeStatement cs in colTrueStment)
                    {
                        arrIf[i].TrueStatements.Add(cs);
                    }
                }               

                return arrIf;
            }
        }

           
        

        /// <summary>
        /// ham de chuyen doi bieu thuc dang !(P(a)) - > ...
        /// </summary>
        /// <param name="s">bieu thuc can chuyen doi</param>
        /// <returns>tra ve bieu thuc moi</returns>
        public string ConvertNotExpression(string s)
        {
            if (s[0] == '!')
            {
                //loai bo '!'
                s = s.Substring(1);
                if (s.Contains(">="))
                {
                    s = s.Replace(">=", "<");
                    return s;
                }
                else
                {
                    if (s.Contains("<="))
                    {
                        s = s.Replace("<=", ">");
                        return s;
                    }
                    else
                    {
                        if (s.Contains("=="))
                        {
                            s = s.Replace("==", "!=");
                            return s;
                        }
                        else
                        {
                            if (s.Contains("!="))
                            {
                                s = s.Replace("!=", "==");
                                return s;
                            }
                            else
                            {
                                if (s.Contains(">"))
                                {
                                    s = s.Replace(">", "<=");
                                    return s;
                                }
                                else
                                {
                                    s = s.Replace("<", ">=");
                                    return s;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                return s;
            }
        }

      
        #endregion

        #region For Statement
        public CodeIterationStatement GenerateForStatement(CodeVariableDeclarationStatement preStatement, CodeBinaryOperatorExpression condition, CodeAssignStatement increment, CodeStatementCollection colStatement)
        {
            CodeIterationStatement forStatement = new CodeIterationStatement();

            forStatement.InitStatement = preStatement;
            forStatement.TestExpression = condition;
            forStatement.IncrementStatement = increment;

            if (colStatement != null)
            {
                foreach (CodeStatement cs in colStatement)
                {
                    forStatement.Statements.Add(cs);
                }
            }
            return forStatement;
        }


        public CodeIterationStatement GenerateForStatement(string sFor,out CodeAssignStatement initKq)
        {
            CodeIterationStatement for2 = new CodeIterationStatement();

            string[] arr = sFor.Split(new string[] { mySymbol.All, mySymbol.Belong, mySymbol.Exist }, StringSplitOptions.RemoveEmptyEntries);

            //luu lai bien chay
            string sNameIndex = arr[0].Trim();

            //xu ly khoang chay
            string[] range = arr[1].Split(new string[] { "{", "}", "." }, StringSplitOptions.RemoveEmptyEntries);

            CodeVariableDeclarationStatement initFor;
            CodeBinaryOperatorExpression checkDT;
            
            CodeAssignStatement inc;

            if (range.Length != 2)
            {
                throw new Exception("Sai cu phap:" + sFor);
            }
            else
            {
                //tao vong lap for(int i=0;i<len;i++)
                //tao cau int i = 0;
                initFor = new CodeVariableDeclarationStatement(typeof(int), sNameIndex);
                initFor.InitExpression = new CodeVariableReferenceExpression(range[0].Trim());

                //tao cau lenh kiem tra dieu kien lap i<n
                checkDT = new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(sNameIndex), CodeBinaryOperatorType.LessThan, new CodeVariableReferenceExpression(range[1].Trim()));

                //tao cau i++;
                inc = new CodeAssignStatement(new CodeVariableReferenceExpression(sNameIndex), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(sNameIndex), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)));

                //nhung dong code sau se tao ra cau (i<n)&& ?? 
                //truong hop ton tai
                if (sFor.Substring(0, 2) == mySymbol.Exist)
                {
                    //tao (i<n)&&(!kq)
                    //tao cau lenh kq = 0
                    string s;
                    if (this.m_parser.Result.Type == "bool")
                    {
                        //tao cau lenh kq = false
                        initKq = this.GenerateAssignStatement(this.m_parser.Result.Name, "false");

                        s = this.m_sNot + this.m_parser.Result.Name;
                        // &&!kq               
                        checkDT = new CodeBinaryOperatorExpression(checkDT, CodeBinaryOperatorType.BooleanAnd, this.GenerateExpression(s));
                    }
                    else
                    {
                        //tao cau lenh kq = 0
                        initKq = this.GenerateAssignStatement(this.m_parser.Result.Name, 0);

                        s = this.m_parser.Result.Name + "==0";
                        // &&!kq               
                        checkDT = new CodeBinaryOperatorExpression(checkDT, CodeBinaryOperatorType.BooleanAnd, this.GenerateCompareStatement("&&",this.ConvertNotExpression("!" + s)));
                    }
                }
                else
                {
                    //truong hop voi moi
                    //tao (i<n)&&(kq)

                    //method.Statements.Add(initKq);                            
                    string s;
                    if (this.m_parser.Result.Type == "bool")
                    {
                        //tao cau lenh kq = 1
                        initKq = this.GenerateAssignStatement(this.m_parser.Result.Name, "true");

                        s = this.m_parser.Result.Name;
                        checkDT = new CodeBinaryOperatorExpression(checkDT, CodeBinaryOperatorType.BooleanAnd, this.GenerateExpression(s));
                    }
                    else
                    {
                        //tao cau lenh kq = 1
                        initKq = this.GenerateAssignStatement(this.m_parser.Result.Name, 1);

                        s = this.m_parser.Result.Name + "==1";
                        checkDT = new CodeBinaryOperatorExpression(checkDT, CodeBinaryOperatorType.BooleanAnd, this.GenerateCompareStatement("&&",s));
                    }
                }
                for2 = this.GenerateForStatement(initFor, checkDT, inc, null);
            }
            return for2;
        }

        public CodeIterationStatement GenerateForStatement(string[] arrSFor, ref int index,out CodeAssignStatement initKq)
        {
            
            if (index == arrSFor.Length - 2)
            {
                CodeIterationStatement for2 = new CodeIterationStatement();

                string[] arr = arrSFor[index].Split(new string[] { mySymbol.All, mySymbol.Belong, mySymbol.Exist }, StringSplitOptions.RemoveEmptyEntries);

                //luu lai bien chay
                string sNameIndex = arr[0].Trim();

                //xu ly khoang chay
                string[] range = arr[1].Split(new string[] { "{", "}", "." }, StringSplitOptions.RemoveEmptyEntries);

                CodeVariableDeclarationStatement initFor;
                CodeBinaryOperatorExpression checkDT;
                
                CodeAssignStatement inc;
                CodeConditionStatement[] condition = null;
                if (range.Length != 2)
                {
                    throw new Exception("Sai cu phap:" + arrSFor[index]);
                }
                else
                {
                    //tao vong lap for(int i=0;i<len;i++)
                    //tao cau int i = 0;
                    initFor = new CodeVariableDeclarationStatement(typeof(int), sNameIndex);
                    initFor.InitExpression = new CodeVariableReferenceExpression(range[0].Trim());

                    //tao cau lenh kiem tra dieu kien lap i<n
                    checkDT = new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(sNameIndex), CodeBinaryOperatorType.LessThan, new CodeVariableReferenceExpression(range[1].Trim()));

                    //tao cau i++;
                    inc = new CodeAssignStatement(new CodeVariableReferenceExpression(sNameIndex), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(sNameIndex), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)));

                    //nhung dong code sau se tao ra cau (i<n)&& ?? 
                    //truong hop ton tai
                    if (arrSFor[index].Substring(0, 2) == mySymbol.Exist)
                    {
                        //tao (i<n)&&(!kq)                        
                        //method.Statements.Add(initKq);
                        string s;
                        if (this.m_parser.Result.Type == "bool")
                        {
                            //tao cau lenh kq = false
                            initKq = this.GenerateAssignStatement(this.m_parser.Result.Name, "false");

                            s = this.m_sNot + this.m_parser.Result.Name;
                            // &&!kq               
                            checkDT = new CodeBinaryOperatorExpression(checkDT, CodeBinaryOperatorType.BooleanAnd, this.GenerateExpression(s));
                        }
                        else
                        {
                            //tao cau lenh kq = 0
                            initKq = this.GenerateAssignStatement(this.m_parser.Result.Name, 0);

                            s = this.m_parser.Result.Name + "==0";
                            // &&!kq               
                            checkDT = new CodeBinaryOperatorExpression(checkDT, CodeBinaryOperatorType.BooleanAnd, this.GenerateCompareStatement("&&",this.ConvertNotExpression("!" + s)));
                        }

                        //sinh ra cau lenh if ben trong vong for cuoi
                        //condition = new CodeConditionStatement();
                        if (this.m_parser.Result.Type == "bool")
                        {
                            condition = this.GeneraterIf(arrSFor[index + 1], this.GenerateAssignStatement(this.m_parser.Result.Name, "true"));
                        }
                        else
                        {
                            condition = this.GeneraterIf(arrSFor[index + 1], this.GenerateAssignStatement(this.m_parser.Result.Name, 1));
                        }
                    }
                    else
                    {
                        //truong hop voi moi
                        //tao (i<n)&&(kq)                        
                        //method.Statements.Add(initKq);                            
                        string s;
                        if (this.m_parser.Result.Type == "bool")
                        {
                            //tao cau lenh kq = 1
                            initKq = this.GenerateAssignStatement(this.m_parser.Result.Name, "true");

                            s = this.m_parser.Result.Name;
                            checkDT = new CodeBinaryOperatorExpression(checkDT, CodeBinaryOperatorType.BooleanAnd, this.GenerateExpression(s));
                        }
                        else
                        {
                            //tao cau lenh kq = 1
                            initKq = this.GenerateAssignStatement(this.m_parser.Result.Name, 1);

                            s = this.m_parser.Result.Name + "==1";
                            checkDT = new CodeBinaryOperatorExpression(checkDT, CodeBinaryOperatorType.BooleanAnd, this.GenerateCompareStatement("&&",s));
                        }

                        //tao cau lenh if ben trong vong for cuoi cung
                        //condition = new CodeConditionStatement();
                        //tao cau lenh if(!P) kq = 0; 
                        if (this.m_parser.Result.Type == "bool")
                        {
                            condition = this.GeneraterIf("!" + arrSFor[index + 1], this.GenerateAssignStatement(this.m_parser.Result.Name, "false"));
                        }
                        else
                        {
                            condition = this.GeneraterIf("!" + arrSFor[index + 1], this.GenerateAssignStatement(this.m_parser.Result.Name, 0));
                        }
                    }
                    for2 = this.GenerateForStatement(initFor, checkDT, inc, null);
                    foreach (CodeConditionStatement ccs in condition)
                    {
                        for2.Statements.Add(ccs);
                    }
                }
                return for2;
            }
            else
            {
                initKq = new CodeAssignStatement();

                CodeIterationStatement for2 = this.GenerateForStatement(arrSFor[index],out initKq);
                index++;                
                
                CodeIterationStatement inFor = this.GenerateForStatement(arrSFor, ref index, out initKq);
                
                for2.Statements.Add(initKq);
                for2.Statements.Add(inFor);

                return for2;
            }
        }

        #endregion

        #region Assign Statement
        /// <summary>
        /// ham de phat sinh ra code co dang x = y
        /// </summary>
        /// <param name="leftAssign">dinh danh trai</param>
        /// <param name="rightAssign">dinh danh phai</param>
        /// <returns>tra ve bieu thuc co dang x = y</returns>
        public CodeAssignStatement GenerateAssignStatement(string leftAssign, string rightAssign)
        {
            //CodeAssignStatement assign = new CodeAssignStatement(new CodeVariableReferenceExpression(leftAssign), new CodeVariableReferenceExpression(rightAssign));
            CodeAssignStatement assign = new CodeAssignStatement(this.GenerateExpression(leftAssign), this.GenerateExpression(rightAssign));

            return assign;
        }
        /// <summary>
        /// ham de phat sinh ra code co dang x = 1;
        /// </summary>
        /// <param name="leftAssign">dinh danh ben trai</param>
        /// <param name="num">number</param>
        /// <returns>tra ve ket qua co dang x = 1</returns>
        public CodeAssignStatement GenerateAssignStatement(string leftAssign, int num)
        {
            CodeAssignStatement assign = new CodeAssignStatement(new CodeVariableReferenceExpression(leftAssign), new CodePrimitiveExpression(num));
            return assign;
        }
        #endregion

        #region Compare Statements
        /// <summary>
        /// ham de phat sinh ra nhung cau co dang so sanh: x > 10, y >= 8
        /// </summary>
        /// <param name="left">dinh danh trai</param>
        /// <param name="op">toan tu so sanh</param>
        /// <param name="num">number ben phai</param>
        /// <returns>tra ve  bieu thuc co dang x > 10</returns>
        public CodeBinaryOperatorExpression GenerateCompareStatement(string left,string op,int num)
        {
            CodeBinaryOperatorExpression c = new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(left),this.GetOperatorType(op), new CodePrimitiveExpression(num));
            return c;
        }

<<<<<<< .mine
        public CodeBinaryOperatorExpression GenerateCompareStatement(int left, string op, int num)
        {
            CodeBinaryOperatorExpression c = new CodeBinaryOperatorExpression(new CodePrimitiveExpression(left), this.GetOperatorType(op), new CodePrimitiveExpression(num));
            return c;
        }

        public CodeBinaryOperatorExpression GenerateCompareStatement(string sOperator, params CodeBinaryOperatorExpression[] left)
        {            
            int i;
            CodeBinaryOperatorExpression sum = null;
            for (i = 0; i < left.Length; i++)
            {
                sum = this.GenerateCodeBinaryOperatorExpression(sOperator, sum, left[i]);
            }
            return sum;
        }

        public CodeBinaryOperatorExpression GenerateCodeBinaryOperatorExpression(string s)
        {
            if (s.Contains(">="))
            {
                return this.GenerateCodeBinaryOperatorExpression(s, ">=");
            }
            else
            {
                if (s.Contains("<="))
                {
                    return this.GenerateCodeBinaryOperatorExpression(s, "<=");
                }
                else
                {
                    if (s.Contains("=="))
                    {
                        return this.GenerateCodeBinaryOperatorExpression(s, "==");
                    }
                    else
                    {
                        if (s.Contains("!="))
                        {
                            return this.GenerateCodeBinaryOperatorExpression(s, "!=");
                        }
                        else
                        {
                            if (s.Contains(">"))
                            {
                                return this.GenerateCodeBinaryOperatorExpression(s, ">");
                            }
                            else
                            {
                                return this.GenerateCodeBinaryOperatorExpression(s, "<");
                            }
                        }
                    }
                }
            }
        }

=======
        public CodeBinaryOperatorExpression GenerateCompareStatement(int left, string op, int num)
        {
            CodeBinaryOperatorExpression c = new CodeBinaryOperatorExpression(new CodePrimitiveExpression(left), this.GetOperatorType(op), new CodePrimitiveExpression(num));
            return c;
        }

        public CodeBinaryOperatorExpression GenerateCompareStatement(params CodeBinaryOperatorExpression[] left)
        {
            /*
            net.kamalpatel.www.ConvertCSharp2VBService o = new net.kamalpatel.www.ConvertCSharp2VBService();
            string lcStr = o.Execute(this.CSharp.Text);
            this.VBText.Text = lcStr.Replace("\n", "\r\n");
             */

            int i;
            CodeBinaryOperatorExpression sum = null;
            for (i = 0; i < left.Length; i++)
            {
                sum = this.GenerateCodeBinaryOperatorExpression(sum, left[i]);
            }
            return sum;
        }
       

>>>>>>> .r17
        /// <summary>
        /// ham de phat sinh ra nhung cau co dang so sanh: x > y, y && z ...
        /// </summary>
        /// <param name="left">dinh danh ben trai</param>
        /// <param name="op">toan tu bat ky: > , || ,...</param>
        /// <param name="right">dinh danh ben phai</param>
        /// <returns>tra ve  bieu thuc co dang x > y</returns>
        public CodeBinaryOperatorExpression GenerateCompareStatement(string left, string op, string right)
        {
            CodeBinaryOperatorExpression c = new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(left), this.GetOperatorType(op), new CodeVariableReferenceExpression(right));
            return c;
        }
<<<<<<< .mine


        public CodeBinaryOperatorExpression GenerateCodeBinaryOperatorExpression(string sOperator, CodeBinaryOperatorExpression left, CodeBinaryOperatorExpression right)
        {
            if (left == null)
            {
                return right;
            }
            else
            {
                //CodeBinaryOperatorType.BooleanAnd
                return new CodeBinaryOperatorExpression(left,this.GetOperatorType(sOperator) , right);
            }
        }

        public CodeBinaryOperatorExpression GenerateCodeBinaryOperatorExpression(string s, string type)
        {
            string[] arr = new string[2];
            string str = "";
            switch (type)
            {
                case ">=":
                    arr = s.Split(new string[] { ">=" }, StringSplitOptions.None);
                    str = ">=";
                    break;
                case "<=":
                    arr = s.Split(new string[] { "<=" }, StringSplitOptions.None);
                    str = "<=";
                    break;
                case "==":
                    arr = s.Split(new string[] { "==" }, StringSplitOptions.None);
                    str = "==";
                    break;
                case "!=":
                    arr = s.Split(new string[] { "!=" }, StringSplitOptions.None);
                    str = "!=";
                    break;
                case "=":
                    arr = s.Split(new string[] { "=" }, StringSplitOptions.None);
                    str = "=";
                    break;
                case "!":
                    arr = s.Split(new string[] { "!" }, StringSplitOptions.None);
                    str = "!";
                    break;
                case ">":
                    arr = s.Split(new string[] { ">" }, StringSplitOptions.None);
                    str = ">";
                    break;
                case "<":
                    arr = s.Split(new string[] { "<" }, StringSplitOptions.None);
                    str = "<";
                    break;
            }

            if (arr.Length == 2)
            {
                if (arr[0][0] == '!')
                {

                }

                if (arr[1][0] == '!')
                {
                }

                CodeBinaryOperatorExpression a = this.GenerateCompareStatement(arr[0], str, arr[1]);

                return a;
            }
            else
            {
                return null;
            }            
        }

        

        //public CodeBinaryOperatorExpression GenerateCompareStatement(params string[] arr)
        //{
        //    int j;
        //    int i;
        //    string[] arrTT = { ">=", "<=", "==", "!=", "=", "!", ">", "<" };

        //    CodeBinaryOperatorExpression[] arrCodeBinary = new CodeBinaryOperatorExpression[arr.Length];

        //    for (i = 0; i < arr.Length; i++)
        //    {               

        //        for (j = 0; j < arrTT.Length; j++)
        //        {
        //            arrCodeBinary[i] = this.GenerateCodeBinaryOperatorExpression(arr[i], arrTT[j]);
        //            if (arrCodeBinary[i] != null)
        //            {
        //                break;
        //            }
        //        }
        //    }

        //    return this.GenerateCompareStatement("&&",arrCodeBinary);
        //}

        public CodeBinaryOperatorExpression GenerateCompareStatement(string sOperator, params string[] arr)
        {
            int j;
            int i;
            string[] arrTT = { ">=", "<=", "==", "!=", "=", "!", ">", "<" };

            CodeBinaryOperatorExpression[] arrCodeBinary = new CodeBinaryOperatorExpression[arr.Length];

            for (i = 0; i < arr.Length; i++)
            {

                for (j = 0; j < arrTT.Length; j++)
                {
                    arrCodeBinary[i] = this.GenerateCodeBinaryOperatorExpression(arr[i], arrTT[j]);
                    if (arrCodeBinary[i] != null)
                    {
                        break;
                    }
                }
            }

            return this.GenerateCompareStatement(sOperator, arrCodeBinary);
        }

=======


        public CodeBinaryOperatorExpression GenerateCodeBinaryOperatorExpression(CodeBinaryOperatorExpression left, CodeBinaryOperatorExpression right)
        {
            if (left == null)
            {
                return right;
            }
            else
            {
                return new CodeBinaryOperatorExpression(left, CodeBinaryOperatorType.BooleanAnd, right);
            }
        }

        public CodeBinaryOperatorExpression GenerateCodeBinaryOperatorExpression(string s, string type)
        {
            string[] arr = new string[2];
            string str = "";
            switch (type)
            {
                case ">=":
                    arr = s.Split(new string[] { ">=" }, StringSplitOptions.None);
                    str = ">=";
                    break;
                case "<=":
                    arr = s.Split(new string[] { "<=" }, StringSplitOptions.None);
                    str = "<=";
                    break;
                case "==":
                    arr = s.Split(new string[] { "==" }, StringSplitOptions.None);
                    str = "==";
                    break;
                case "!=":
                    arr = s.Split(new string[] { "!=" }, StringSplitOptions.None);
                    str = "!=";
                    break;
                case "=":
                    arr = s.Split(new string[] { "=" }, StringSplitOptions.None);
                    str = "=";
                    break;
                case "!":
                    arr = s.Split(new string[] { "!" }, StringSplitOptions.None);
                    str = "!";
                    break;
                case ">":
                    arr = s.Split(new string[] { ">" }, StringSplitOptions.None);
                    str = ">";
                    break;
                case "<":
                    arr = s.Split(new string[] { "<" }, StringSplitOptions.None);
                    str = "<";
                    break;
            }

            if (arr.Length == 2)
            {
                if (arr[0][0] == '!')
                {

                }

                if (arr[1][0] == '!')
                {
                }

                CodeBinaryOperatorExpression a = this.GenerateCompareStatement(arr[0], str, arr[1]);

                return a;
            }
            else
            {
                return null;
            }            
        }

        

        public CodeBinaryOperatorExpression GenerateCompareStatement(params string[] arr)
        {
            int j;
            int i;
            string[] arrTT = { ">=", "<=", "==", "!=", "=", "!", ">", "<" };

            CodeBinaryOperatorExpression[] arrCodeBinary = new CodeBinaryOperatorExpression[arr.Length];

            for (i = 0; i < arr.Length; i++)
            {
                arr[i] = arr[i].Replace("(", "");
                arr[i] = arr[i].Replace(")", "");

                for (j = 0; j < arrTT.Length; j++)
                {
                    arrCodeBinary[i] = this.GenerateCodeBinaryOperatorExpression(arr[i], arrTT[j]);
                    if (arrCodeBinary[i] != null)
                    {
                        break;
                    }
                }
            }

            return this.GenerateCompareStatement(arrCodeBinary);
        }

>>>>>>> .r17
        #endregion

        #region declaration statement
        /// <summary>
        /// ham de phat sinh ra cau khai bao bien. vd:  int a = 10, string b = "huy" ...
        /// </summary>
        /// <param name="para">tham so can khai bao</param>
        /// <param name="iValue">neu para la gia tri don thi iValue la gia tri tham so,
        /// Neu para la bien kieu array thi iValue la gia tri do dai cua mang</param>
        /// <returns>tra ve cau khai bao bien</returns>
        public CodeVariableDeclarationStatement GenerateVariableDeclaration(Parameter para, string iValue)
        {
<<<<<<< .mine
            if (iValue == null)
            {
                CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement(new CodeTypeReference(para.SystemType), para.Name);
                return variable;                
            }
=======
            if (iValue == null)
            {
                CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement(new CodeTypeReference(para.SystemType), para.Name);
                return variable;
                
            }
>>>>>>> .r17
            //tham so co dang la 1 array
            if (para.IsArr)
<<<<<<< .mine
            {                
                CodeArrayCreateExpression ca = new CodeArrayCreateExpression(para.SystemType, this.GenerateExpression(iValue));
=======
            {
                CodeArrayCreateExpression ca = new CodeArrayCreateExpression(para.SystemType, (int)iValue);
>>>>>>> .r17

<<<<<<< .mine
                CodeVariableDeclarationStatement cv = new CodeVariableDeclarationStatement(para.SystemType + "[]", para.Name, ca);
=======
                CodeVariableDeclarationStatement cv = new CodeVariableDeclarationStatement(para.SystemType + "[]", para.Name, ca);
                
>>>>>>> .r17
                return cv;
            }
            else
            {
<<<<<<< .mine
                CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement(new CodeTypeReference(para.SystemType), para.Name, new CodePrimitiveExpression(iValue));
                return variable;
            }
        }
=======
                CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement(new CodeTypeReference(para.SystemType), para.Name, new CodePrimitiveExpression(iValue));
>>>>>>> .r17

        /// <summary>
        /// generate ra 1 cau khai bao bien. vd: int a = 0;
        /// </summary>
        /// <param name="name">ten bien</param>
        /// <param name="type">loai du lieu</param>
        /// <param name="iValue">gia tri</param>
        /// <returns>tra ve cau khai bao bien</returns>
        public CodeVariableDeclarationStatement GenerateVariableDeclaration(string name, string type, object iValue)
        {
            if (iValue == null)
            {
                CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement(this.GetCodeTypeReference(type), name);
                return variable;
            }
            else
            {
                CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement(this.GetCodeTypeReference(type), name, new CodePrimitiveExpression(iValue));
                return variable;
            }
        }             
        #endregion

        #region Comment Statement
        /// <summary>
        /// ham generate ra comment
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public CodeCommentStatement GenerateComment(string text)
        {
            CodeCommentStatement comment = new CodeCommentStatement(text);
            return comment;
        }
        #endregion
        #endregion

        /// <summary>
        /// ham de phat sinh ra 1 expression
        /// </summary>
        /// <param name="s">chuoi expression</param>
        /// <returns>tra ve 1 CodeSnipperExpression</returns>
        public CodeSnippetExpression GenerateExpression(string s)
        {
            CodeSnippetExpression cse = new CodeSnippetExpression(s);            
            
            return cse;
        }

        /// <summary>
        /// ham phat sinh ra 1 class
        /// </summary>
        /// <param name="sName">ten cua class</param>
        /// <param name="att">thuoc tinh cua class (public,private..)</param>
        /// <param name="arrFields">mang cac fields ( su dung ham generateField de khoi tao)</param>
        /// <param name="arrMethods">mang cac methods (su dung ham GenerateMethod de khoi tao)</param>
        /// <returns>tra ve 1 class</returns>
        public CodeTypeDeclaration GenerateClass(string sName,string att,CodeMemberField[] arrFields,CodeMemberMethod[] arrMethods)
        {
            CodeTypeDeclaration ctd = new CodeTypeDeclaration(sName);
            ctd.IsClass = true;
            ctd.TypeAttributes = this.GetTypeAttribute(att);
            

            //add fields
            if (arrFields != null)
            {
                foreach (CodeMemberField c in arrFields)
                {
                    ctd.Members.Add(c);
                }
            }

            //add methods
            if (arrMethods != null)
            {
                foreach (CodeMemberMethod c in arrMethods)
                {
                    ctd.Members.Add(c);
                }
            }

            //add comments
            ctd.Comments.Add(this.GenerateComment(""));
            ctd.Comments.Add(this.GenerateComment("Add code here..."));
            ctd.Comments.Add(this.GenerateComment(""));

            //add properties cho fields
            
            //add constructors

            return ctd;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sName"></param>
        /// <param name="att"></param>
        /// <returns></returns>
        public CodeTypeDeclaration GenerateClass(string sName, string att)
        {
            CodeTypeDeclaration ctd = new CodeTypeDeclaration(sName);
            ctd.IsClass = true;
            ctd.TypeAttributes = this.GetTypeAttribute(att);

            //add comments
            ctd.Comments.Add(this.GenerateComment(""));
            ctd.Comments.Add(this.GenerateComment("Add code here..."));
            ctd.Comments.Add(this.GenerateComment(""));

<<<<<<< .mine

            //add fields va properties
            foreach (Parameter p in this.m_parser.ArrPara)
            {                
                ctd.Members.Add(this.GenerateField(p));
                ctd.Members.Add(this.GenerateProperties(p, true, true));
=======
            if (this.m_parser.Num == 1)
            {
                //add fields va properties
                foreach (Parameter p in this.m_parser.ArrPara)
                {
                    ctd.Members.Add(this.GenerateField(p.SystemType, p.Name, "private"));
                    ctd.Members.Add(this.GenerateProperties("Property_" + p.Name.ToUpper(), p.SystemType, p.Name, true, true));
                }

                //add result
                ctd.Members.Add(this.GenerateField(this.m_parser.Result.SystemType, this.m_parser.Result.Name, "private"));
                ctd.Members.Add(this.GenerateProperties("Property_" + this.m_parser.Result.Name.ToUpper(), this.m_parser.Result.SystemType, this.m_parser.Result.Name, true, true));

>>>>>>> .r17
            }
<<<<<<< .mine

            //add result
            ctd.Members.Add(this.GenerateField(this.m_parser.Result));
            ctd.Members.Add(this.GenerateProperties(this.m_parser.Result, true, true));


=======
            else
            {
                //lam bai 2 o day
            }
>>>>>>> .r17
            //add constructors
            ctd.Members.Add(this.GenerateConstructor());

            return ctd;
        }

        /// <summary>
        /// ham de generate ra class
        /// </summary>
        /// <param name="sFileName">ten file muon luu</param>
        public void GenerateSourceCode()
<<<<<<< .mine
        {            
            string startup = Form1.m_startUp + this.m_sFileName + this.m_sFileExtension;
            StreamWriter sw = new StreamWriter(startup, false);
=======
        {
            string startup = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
            startup += this.m_sFileName + this.m_sFileExtension;
            startup = startup.Substring(6);
            StreamWriter sw = new StreamWriter(startup, false);
            IndentedTextWriter itw = new IndentedTextWriter(sw, "   ");
>>>>>>> .r17
                                   
            ICodeGenerator generateCode = this.m_myProvider.CreateGenerator(sw);

            CodeGeneratorOptions codeOption = new CodeGeneratorOptions();
            codeOption.BlankLinesBetweenMembers = true;
            codeOption.ElseOnClosing = false;

            CodeCompileUnit compileUnit = new CodeCompileUnit();                        

            //phat sinh ra ten cua namespace trung ten voi ten ham dac ta
            CodeNamespace cn = this.GenerateNamespace(this.m_parser.NameMethod);
            compileUnit.Namespaces.Add(cn);

            //include thu vien
            foreach (CodeNamespaceImport cni in this.GenerateImport(this.m_arrNamespaceImport))
            {
                cn.Imports.Add(cni);
            }

            //phat sinh class dac ta     
            CodeTypeDeclaration myClass = this.GenerateClass(this.m_parser.NameMethod, "public");

<<<<<<< .mine
            //phat sinh ham nhap
            CodeMemberMethod inputMethod = this.GenerateInputMethod(this.m_parser.NameMethod, this.m_parser.ArrPara, "public", null, null);
            myClass.Members.Add(inputMethod);
=======
            //phat sinh ham nhap
            CodeMemberMethod inputMethod = this.GenerateInputMethod(this.m_parser.NameMethod, this.m_parser.ArrPara, "public", null,null);
            myClass.Members.Add(inputMethod);
>>>>>>> .r17
            cn.Types.Add(myClass);

            //phat sinh ham xu ly
            CodeMemberMethod exeMethod = this.GenerateExecuteMethod(this.m_parser.NameMethod, "public", null);
            myClass.Members.Add(exeMethod);

            //phat sinh ham kiem tra
            CodeMemberMethod checkingMethod = this.GenerateCheckingMethod(this.m_parser.NameMethod, "public", null);
            myClass.Members.Add(checkingMethod);

            //ham xuat
            CodeMemberMethod outputMethod = this.GenerateOutputMethod(this.m_parser.NameMethod, "public","public", null);
            myClass.Members.Add(outputMethod);

            //phat sinh lop Program chinh
            CodeTypeDeclaration mainClass = this.GenerateClass("Program", "public", null, null);
            //phat sinh cac method cho class Program
            CodeMemberMethod mainMethod = this.GenerateMethod("Main", null, "static", null);                     

            mainClass.Members.Add(mainMethod);
            cn.Types.Add(mainClass);

<<<<<<< .mine
            //add code vao mainMethod            
            //T_T!
=======
            //add code vao mainMethod
            //T_T!

            //tao cau lenh new
            CodeTypeReference myType = new CodeTypeReference();
            myType.BaseType = myClass.Name;

            //khai bao bien
            CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement(myType, "testclass");
            mainMethod.Statements.Add(variable);

            //tao cau lenh new
            CodeObjectCreateExpression objectCreate1 = new CodeObjectCreateExpression(myType, new CodeExpression[] { });
                        
            //gan bien = new...
            CodeAssignStatement assign = new CodeAssignStatement(new CodeVariableReferenceExpression("testclass"), objectCreate1);
            mainMethod.Statements.Add(assign);


            //tao doi tuong tham chieu den class phat sinh
            CodeTypeReferenceExpression ctre = new CodeTypeReferenceExpression(myType);
            
            
            //tao cau xuat thong bao nhap
            //CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(ctre, "testclass.Input_" + myClass.Name);
            CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression();
            cs1.Method.MethodName = "testclass.Input_" + myClass.Name;            
            
            mainMethod.Statements.Add(cs1);                                  
           
            //tao cau lenh if
           
            CodeConditionStatement conditionStatement = new CodeConditionStatement();

            //cau lenh o if
            CodeMethodInvokeExpression cs2 = new CodeMethodInvokeExpression();
            cs2.Method.MethodName = "testclass.KiemTra_" + myClass.Name;
            
            CodeBinaryOperatorExpression c = new CodeBinaryOperatorExpression(cs2 ,CodeBinaryOperatorType.ValueEquality , new CodePrimitiveExpression(1));
            
            conditionStatement.Condition = c;

            //cau lenh khi if dung
            CodeMethodInvokeExpression cs3 = new CodeMethodInvokeExpression();
            cs3.Method.MethodName = "testclass.Execute_" + myClass.Name;
            
            CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression();
            cs4.Method.MethodName = "testclass.Output_" + myClass.Name;

            conditionStatement.TrueStatements.Add(cs3);
            conditionStatement.TrueStatements.Add(cs4);         
          
            mainMethod.Statements.Add(conditionStatement);

            generateCode.GenerateCodeFromCompileUnit(compileUnit, itw, codeOption);
>>>>>>> .r17

            //tao cau lenh new
            CodeTypeReference myType = new CodeTypeReference();
            myType.BaseType = myClass.Name;

            //khai bao bien
            CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement(myType, "testclass");
            mainMethod.Statements.Add(variable);

            //tao cau lenh new
            CodeObjectCreateExpression objectCreate1 = new CodeObjectCreateExpression(myType, new CodeExpression[] { });
                        
            //gan bien = new...
            CodeAssignStatement assign = new CodeAssignStatement(new CodeVariableReferenceExpression("testclass"), objectCreate1);
            mainMethod.Statements.Add(assign);

            //tao doi tuong tham chieu den class phat sinh
            CodeTypeReferenceExpression ctre = new CodeTypeReferenceExpression(myType);            
            
            //tao cau xuat thong bao nhap
            //CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(ctre, "testclass.Input_" + myClass.Name);
            CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression();
            cs1.Method.MethodName = "testclass.Input_" + myClass.Name;            
            
            mainMethod.Statements.Add(cs1);                                  
           
            //tao cau lenh if
           
            CodeConditionStatement conditionStatement = new CodeConditionStatement();

            //cau lenh o if
            CodeMethodInvokeExpression cs2 = new CodeMethodInvokeExpression();
            cs2.Method.MethodName = "testclass.KiemTra_" + myClass.Name;
            
            //CodeBinaryOperatorExpression c = new CodeBinaryOperatorExpression(cs2 ,CodeBinaryOperatorType.ValueEquality , new CodePrimitiveExpression(1));
            
            //conditionStatement.Condition = c;
            CodeMethodInvokeExpression cs5 = new CodeMethodInvokeExpression();
            cs5.Method.MethodName = "testclass.KiemTra_" + myClass.Name;
            conditionStatement.Condition = cs5;

            //cau lenh khi if dung
            CodeMethodInvokeExpression cs3 = new CodeMethodInvokeExpression();
            cs3.Method.MethodName = "testclass.Execute_" + myClass.Name;
            
            CodeMethodInvokeExpression cs4 = new CodeMethodInvokeExpression();
            cs4.Method.MethodName = "testclass.Output_" + myClass.Name;

            conditionStatement.TrueStatements.Add(cs3);
            conditionStatement.TrueStatements.Add(cs4);
                                  
            mainMethod.Statements.Add(conditionStatement);

            generateCode.GenerateCodeFromCompileUnit(compileUnit, sw, codeOption);

            sw.Close();
            
        }

        /// <summary>
        /// ham dung de compile code
        /// </summary>
        /// <param name="provider">bien dich cs hay vb?</param>
        /// <param name="sourceFile">ten file source</param>
        /// <param name="exeFile">ten file exe</param>
        /// <returns>tra ve ket qua sau khi compile</returns>
        public static CompilerResults CompileCode(CodeDomProvider provider, String sourceFile, String exeFile)
        {
            ICodeCompiler compiler = provider.CreateCompiler();

            //cac dll can thiet de compile code
            String[] referenceAssemblies = { "System.dll" };
            CompilerParameters cp = new CompilerParameters(referenceAssemblies, exeFile, false);

            cp.GenerateExecutable = true;

            CompilerResults cr = compiler.CompileAssemblyFromFile(cp, sourceFile);

            return cr;
        }           
                    

        #endregion
    }        

    public class VBGenerator : Generator
    {        
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="sFileName">ten file source code muon luu</param>
        public VBGenerator(Parser parser)
        {
<<<<<<< .mine
            this.m_myProvider = new VBCodeProvider();
            this.m_parser = parser;
=======
            this.m_parser = parser;
>>>>>>> .r17

            this.m_sNot = "Not ";

            //lay ten mo rong
            if (this.m_myProvider.FileExtension[0] == '.')
            {
                this.m_sFileExtension = this.m_myProvider.FileExtension;
            }
            else
            {
                this.m_sFileExtension = "." + this.m_myProvider.FileExtension;
            }

            //doi cac dau ngoac [] -> ()
            string[] arrOld = { "[", "]" };
            string[] arrNew = { "(", ")" };
            int i;
            int j;
            for (i = 0; i < arrNew.Length; i++)
            {
                for (j = 0; j < this.m_parser.PostCondition.Length; j++)
                {
                    this.m_parser.PostCondition[j] = this.m_parser.PostCondition[j].Replace(arrOld[i], arrNew[i]);                                
                }
                for (j = 0; j < this.m_parser.PreCondition.Length; j++)
                {
                    this.m_parser.PreCondition[j] = this.m_parser.PreCondition[j].Replace(arrOld[i], arrNew[i]);
                }
            }                
        }
    }

    public class CSharpGenerator : Generator
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sFileName"></param>
        public CSharpGenerator(Parser parser)
        {            
            this.m_myProvider = new CSharpCodeProvider();
            this.m_parser = parser;
            this.m_sNot = "!";

            //lay ten mo rong
            if (this.m_myProvider.FileExtension[0] == '.')
            {
                this.m_sFileExtension = this.m_myProvider.FileExtension;
            }
            else
            {
                this.m_sFileExtension = "." + this.m_myProvider.FileExtension;
            }
        }
    }
}